const fs = require('fs');
const Koa = require('Koa');
const Router = require('koa-router');
const koaStatic = require('koa-static');
const path = require('path');
const { renderToHTML, routes } = require('./ssr/ssr.js');
const { matchRoutes } = require('react-router-config');
const Loadable = require('react-loadable');
const cors = require('koa2-cors'); //解决跨域
const bodyParser = require('koa-bodyparser'); //解析post请求
const koaRouterProxy = require('koa-router-proxy');

const config = {
  port: 3030, // 服务器端口
  proxy: {
    // 代理请求
    target: 'https://www.h5ds.com',
    changeOrigin: true
  }
};

function getIndexHTML() {
  return new Promise((resolve, reject) => {
    fs.readFile(path.join(__dirname, './static/index.html'), 'utf8', function (err, data) {
      if (err) {
        reject();
        return console.log(err);
      }
      resolve(data);
    });
  });
}

async function mainServer() {
  // 实例化 koa
  const app = new Koa();

  // 解决跨域
  app.use(cors());

  //解析post请求
  app.use(bodyParser());

  // 静态资源
  app.use(
    koaStatic(path.join(__dirname, './static'), {
      maxage: 365 * 24 * 60 * 1000,
      index: 'root'
      // 这里配置不要写成'index'就可以了，因为在访问localhost:3030时，不能让服务默认去加载index.html文件，这里很容易掉进坑。
    })
  );

  const indexHTML = await getIndexHTML();

  // 设置路由
  app.use(
    new Router()
      .post('/api/*', koaRouterProxy('*', config.proxy))
      .get('/api/*', koaRouterProxy('*', config.proxy))
      .put('/api/*', koaRouterProxy('*', config.proxy))
      .delete('/api/*', koaRouterProxy('*', config.proxy))
      .get('*', async (ctx, next) => {
        const [routeAll, routeTarget] = matchRoutes(routes, ctx.request.path);
        if (!routeTarget) {
          ctx.response.body = ctx.request.path; // shtml.replace('{{root}}', '404');
        } else {
          // 如果没有做SSR，应该直接显示local App模块
          let shtml = 'loading',
            scripts = ``;

          // 选择性的做ssr
          if (routeTarget.route.ssr) {
            const data = await renderToHTML(routeTarget.route, {
              location: ctx.request.path,
              context: { ...routeTarget.match }
            });
            shtml = data.shtml || 'loading';
            scripts = data.scripts;
          }
          ctx.response.type = 'html'; //指定content type
          ctx.response.body = indexHTML.replace('{{root}}', shtml).replace('{{scripts}}', scripts);
        }
      })
      .routes()
  );

  await Loadable.preloadAll();

  app.listen(config.port, function () {
    console.log('服务器启动，监听 port： ' + config.port + '  running~');
  });
}

mainServer();
